package ftp

import (
	"bufio"
	"fmt"
	"gin/func"
	"gin/model"
	FtpClient "github.com/jlaffaye/ftp"
	"io"
	"net"
	"os"
	"path/filepath"
	"reflect"
	"runtime/debug"
	"strconv"
	"strings"
	"time"
)

type GpFtpS struct {
	dataParsing    *DataParsing
	ftpConnectInfo *model.FtpConnectInfo
	ftpInfo        *model.FtpInfo
	DataIndexM     *model.DataIndexM
	Log            *_func.StyleLog
	Ftp            *gpFtp
	DataUserS      *DataUserS
}

func NewGpFtp() *GpFtpS {
	return &GpFtpS{
		NewDataParsing(),
		model.NewFtpConnectInfo(),
		model.NewFtpInfo(),
		model.NewDataIndexM(),
		&_func.StyleLog{},
		&gpFtp{},
		NewDataUserS(),
		//Inject services
	}
}

type gpFtp struct {
	sshClient      *FtpClient.ServerConn //ssh客户端
	sshStatus      bool                  //ssh客户端状态
	sshConnectNum  int                   //ssh重复连接次数 默认 3
	sftpStatus     bool                  //sftp客户端状态
	sftpConnectNum int                   //sftp重复连接次数 默认 3
	cdDir          bool                  //进入目录状态
	config         struct {
		userName       string //用户名
		password       string //密码
		Address        string //ip地址或连接地址
		port           string //端口
		id             string //数据来源id
		remoteFilePath string //远程路径目录
		localDir       string //本地路径目录
		ftpType        string //FTP类型
	}
	Log *_func.StyleLog
}

type scumFileFtp struct {
	name     string //文件名称
	size     int64  //文件大小
	status   bool   //文件删除状态
	dwStatus bool   //文件下载状态
	fileName string //文件后缀名
	fileTime string //文件时间
}

func (g *GpFtpS) GgWorker(worker *Woker) {
	id := strconv.FormatInt(worker.FtpId, 10)

	//发送创建成功
	worker.ReceiveChan <- "WokerCreatSuccess"

	//初始化日志id
	g.Log.NewLog(id)
	defer func() {
		if r := recover(); r != nil {

			fmt.Println("最后错误捕捉", r)
			fmt.Println("最后错误捕捉", string(debug.Stack()))

		}
	}()
	defer func() {
		var err string
		if r := recover(); r != nil {

			// 处理panic，记录日志或返回错误信息给客户端
			g.Log.FtpLogGer2("协程捕获错误", r)
			g.Log.FtpLogGer2("协程捕获错误", debug.Stack())

			err = fmt.Sprintf("%v", r)
			if strings.Contains(err, "no such username") {
				worker.ReceiveChan <- "UserErr"
				err = "账号或密码错误,错误原因:不存在用户"

			}
			if strings.Contains(err, "530 wrong password") {
				worker.ReceiveChan <- "UserErr"
				err = "密码错误,错误原因:密码报错"
			}

			//发送异常关闭
			worker.ReceiveChan <- "tryCloser"

			//fmt.Println("666", err)
			//g.ftpInfo.UpdateFtpErr(worker.FtpId, err)
		} else {
			err = "信号停止"
		}

		g.Ftp.CloseConnect()
	}()

	g.Log.FtpLogGer("开始执行线程")
	g.Log.FtpLogGer2("收到数据", worker)
	fmt.Println("收到数据", worker)
	//修改woker状态
	g.ftpInfo.SetWokerStatus(worker.FtpId, 1)
	//woker 启动时间
	g.ftpConnectInfo.SaveFtpWorkCreatedTime(worker.FtpId)

	ConnectInfo := g.ftpConnectInfo.GetConnectInfo(worker.FtpId)

	g.Log.FtpLogGer2("连接信息", ConnectInfo.FtpDirectory)
	fmt.Println("连接信息", ConnectInfo.FtpDirectory)

	var scumFtpDir string
	//判断目录是否存在
	if _, err := os.Stat(ConnectInfo.FtpDirectory); os.IsNotExist(err) {
		// 目录不存在，创建目录
		id = strconv.FormatInt(worker.FtpId, 10)

		scumFtpDir = "public/ftpLog/log_" + id

		err := os.MkdirAll("public/ftpLog/log_"+id, 0755)
		if err != nil {
			g.Log.FtpLogGer2("创建目录错误", "public/ftpLog/log_"+id)
			fmt.Println("创建目录错误" + "public/ftpLog/log_" + id)
			panic("目录异常")
			return
		}
		//保存项目目录
		g.Log.FtpLogGer("保存目录")
		fmt.Println("保存目录")
		g.ftpConnectInfo.SaveDirectory(worker.FtpId, scumFtpDir)
		g.Log.FtpLogGer("保存目录成功")
		fmt.Println("保存目录成功")

	} else {
		// 目录已存在
		g.Log.FtpLogGer("目录已存在")
		scumFtpDir = ConnectInfo.FtpDirectory
		id = strconv.FormatInt(worker.FtpId, 10)
	}

	//传递日志到ftp 结构体
	g.Ftp.Log = g.Log

	g.Ftp.config.id = id
	g.Ftp.config.userName = worker.FtpUserName
	g.Ftp.config.password = worker.FtpPassword
	g.Ftp.config.Address = worker.FtpAddress
	g.Ftp.config.port = worker.Port
	g.Ftp.config.localDir = scumFtpDir
	g.Ftp.config.ftpType = worker.FtpType

	//FTP路径固定  如不固定则连接时设定
	g.Ftp.config.remoteFilePath = "/SCUM/Saved/SaveFiles/Logs/"
	g.Ftp.sshConnectNum = 2
	var downloadFile []scumFile
	//g.ftpInfo.UpdateFtpStatus(worker.FtpId, 2)
	_, status, err := g.Ftp.GetSshId()
	//处理状态  第一次连接后 用户才能再次 启动这个任务 执行 否者 外部无法执行这个任务

	if status == false {

		worker.ReceiveChan <- "FirstConnectFailed"

		panic(err)
		return
	} else {

		worker.ReceiveChan <- "FirstConnectSuccess"
		//g.ftpInfo.UpdateFtpStatus(worker.FtpId, 1)
	}

	//用户列表数据处理 返回用户数据 用做本地数据 处理用户数据变更
	UserData := g.DataUserS.EventUserListData(worker.FtpId)
	g.DataUserS.EventUserEconnomyData(worker.FtpId, &UserData)

	g.dataParsing.Log = g.Log

	var fotSTtus = true
	var forChanStatus bool
	wokerXtNum := 0
	for fotSTtus {

		// 携程通信  接收外部数据
		//接收消息
		//接收消息
		forChanStatus = true
		for forChanStatus {
			select {
			case response := <-worker.SendChan:
				switch response {
				case "UserStop":
					//用户主动关闭结束
					worker.ReceiveChan <- "endUserStop"
					g.Log.FtpLogGer3("用户主动关闭-接收到关闭信号-删除woker数据", worker)
					return
				case "xtOutStop":
					//心跳超时了 直接退出去
					worker.ReceiveChan <- "xtOutStop"
					return
				case "dataOutStop":
					worker.ReceiveChan <- "dataOutStop"
					//data超时了 直接退出去
					return
				case "XT":
					wokerXtNum = 0
				default:
					g.Log.FtpLogGer(response)
				}
				break
			default:
				forChanStatus = false
				break
			}
		}
		if wokerXtNum > 60 {
			g.Log.FtpLogGer3("master心跳停止 超过10秒 强行停止", worker)
			return
		}
		wokerXtNum = wokerXtNum + 1

		//发送协程心跳
		worker.ReceiveChan <- "xintiao"

		//g.ftpInfo.UpdateEventStatus(worker.FtpId, 1)

		//清空数据
		downloadFile = downloadFile[:0]
		//获取ftp连接id
		_, status, err := g.Ftp.GetSshId()

		if status == false {
			panic(err)
			return
		} else {
			//连接成功发送连接刷新状态

			worker.ReceiveChan <- "ConnectSuccess"

			//g.ftpConnectInfo.SaveConnectTime(worker.FtpId, 1)
		}
		fmt.Println(id, "获取远程文件")
		//获取远程文件
		downloadFile, status = g.Ftp.GetFtpDownloadFile()
		if status == false {
			g.Log.FtpLogGer("获取远程文件失败")
			continue
		}
		//下载文件
		g.Ftp.DownloadFile(downloadFile)

		//保存文件下载时间
		g.ftpConnectInfo.SaveFileDownloadTime(worker.FtpId)

		g.Log.FtpLogGer("下载文件成功")
		fmt.Println(id, "获取下载文件成功")
		/*
			文件下载 利用文件修改时间  来决定 需要解析的文件  防止 下载成功解析失败的问题

			每次解析成功记录一个解析时间   文件修改时间大于 解析时间的为需要解析的文件  然后在过滤 解析保存
		*/

		//获取本地下载的文件
		downloadFile := g.GetDownloadFile(worker.FtpId, scumFtpDir)

		g.Log.FtpLogGer(fmt.Sprintf("解析下载文件成功", "长度", len(downloadFile)))
		//fmt.Println("获取的文件", downloadFile)
		fmt.Println("id:", id, "获取下载文件成功", "长度", len(downloadFile))

		/*downloadFilex := scumFile{name: "chat_20240615000140.log", size: 123456, status: true, dwStatus: true}
		downloadFile := append(downloadFile, downloadFilex)

		//测试数据.....................
		downloadFilex = scumFile{name: "chat_20240614080127.log", size: 123456, status: true, dwStatus: true}
		downloadFile = append(downloadFile, downloadFilex)*/

		//.......................
		if len(downloadFile) > 0 {
			g.Log.FtpLogGer("开始解析数据")
			g.dataParsing.RunParsing(userData{userId: worker.UserId, ip: worker.FtpAddress, ftpInfoId: ConnectInfo.FtpInfoId}, downloadFile, &UserData)
		} else {
			g.Log.FtpLogGer("没有要下载的文件")
			fmt.Println("无文件")
		}

		str := strconv.FormatInt(worker.WokerOutTime, 10)
		g.Log.FtpLogGer(worker.HeartbeatId + "心跳超时:" + str)
		g.Log.FtpLogGer("等待60秒下载")
		//fmt.Println(downloadFile)
		//修改数据更新时间
		worker.ReceiveChan <- "dataUpdate"

		g.ftpInfo.SaveDataUpdatedTime(worker.FtpId)
		//60秒下载一次
		time.Sleep(3 * time.Second)
	}
}

// 获取id
func (f *gpFtp) GetSshId() (*FtpClient.ServerConn, bool, error) {

	//连续三次失败 则中断
	var err error
	for i := 0; i < f.sshConnectNum; i++ {
		if f.sshStatus == false || f.sshClient == nil {
			f.Log.FtpLogGer2("开始连接ftp", fmt.Sprintf("第", i+1, "次"))
			fmt.Println("开始连接ftp", "第", i+1, "次")
			f.sshClient, f.sshStatus, err = f.ConnectFtp()
			if f.sshStatus == false {
				//如果获取连接错误就跳过循环重新获取
				f.Log.FtpLogGer2("开始连接FTP", fmt.Sprintf("获取ftp 客户端失败", "第", i+1, "次"))
				fmt.Println("FTP 客户端失败", "第", i+1, "次")
				continue
			} else {
				return f.sshClient, true, nil
			}
		} else {
			return f.sshClient, true, nil
		}

	}
	return nil, false, err
}

// 获取sftp
func (f *gpFtp) GetFtpClient() (*FtpClient.ServerConn, bool, error) {

	return f.GetSshId()
}

// 协程中进入目录 防卡死
func FtpChangeDir(FtpConn **FtpClient.ServerConn, remoteFilePath string, errR *error, status *bool) {

	*status = false
	err := (*FtpConn).ChangeDir(remoteFilePath)
	if err != nil {
		*status = false
	} else {
		*status = true
	}
	*errR = err

}

// 协程中获取文件目录 防卡死
func FtpList(FtpConn **FtpClient.ServerConn, remoteFilePath string, FileList *[]*FtpClient.Entry, errR *error, status *bool) {

	*status = false
	FileListR, err := (*FtpConn).List(remoteFilePath)
	if err != nil {
		*status = false
	} else {
		*status = true
	}
	*FileList = FileListR
	*errR = err

}

// 获取远程文件 过滤要下载的文件
func (f *gpFtp) GetFtpDownloadFile() ([]scumFile, bool) {
	var scumFileArr []scumFile
	var FileList []*FtpClient.Entry
	var err error
	var status bool
	//fmt.Println("远程文件初始化状态:", scumFileArr)

	if f.cdDir == false {
		//进入目录
		for i := 0; i < 2; i++ {
			status = false
			f.Log.FtpLogGer("开始进入目录")
			go FtpChangeDir(&f.sshClient, f.config.remoteFilePath, &err, &status)
			for j := 0; j < 30; j++ {
				// 休眠一段时间
				time.Sleep(1 * time.Second)
				f.Log.FtpLogGer2("等待进入目录", j)
				fmt.Println("等待打开", j)
				//设定3分钟超时
				if status {
					break
				}
			}
			if status {
				f.Log.FtpLogGer("进入目录成功")
				fmt.Println("进入目录成功", "第", i+1, "次", err)
				f.cdDir = true
				break
			}
			if err != nil {
				fmt.Println("进入目录错误:", "第", i+1, "次", err)
				f.Log.FtpLogGer2("进入目录错误", err)
			}
		}
		if !status { // 当 i 等于 3 且最后一次尝试仍然失败时
			f.Log.FtpLogGer2("进入目录", fmt.Sprintf("进入目录失败,开始返回", err))
			f.sshStatus = false
			panic(err)
		}
	}
	fmt.Println("开始打开目录")
	for i := 0; i < 2; i++ {
		status = false
		f.Log.FtpLogGer("开始打开目录")
		go FtpList(&f.sshClient, f.config.remoteFilePath, &FileList, &err, &status)
		for j := 0; j < 180; j++ {
			// 休眠一段时间
			f.Log.FtpLogGer2("获取文件列表", j)
			time.Sleep(1 * time.Second)
			//设定3分钟超时
			if status {
				break
			}
		}
		//返回一个文件数组
		//FileList[0].Name

		if status {
			fmt.Println(f.config.id, "获取文件列表成功", "第", i+1, "次", len(FileList))
			break
		}

		if err != nil {
			fmt.Println("获取文件列表错误:", "第", i+1, "次", err)
			f.Log.FtpLogGer2("获取文件列表错误", err)
			panic(err)
		}
	}

	if !status { // 当 i 等于 3 且最后一次尝试仍然失败时
		f.Log.FtpLogGer2("获取远程文件失败", fmt.Sprintf("开始返回", "第", 1, "次", err))
		f.sshStatus = false
		panic(err)
	}

	//fmt.Println("目录为:", FileList)
	//fmt.Println("本地文件初始化状态:", scumFileArr)
	//远程文件提取
	for _, ftpFile := range FileList {
		//fmt.Println("文件类型为:", ftpFile.Type.String(), ftpFile.Name, ftpFile.Size, ftpFile.Target)
		//panic("目录类型为:" + ftpFile.Type.String())
		if ftpFile.Type.String() == "file" {
			//只加入文件类型
			scumF := scumFile{name: ftpFile.Name, size: int64(ftpFile.Size)}
			scumFileArr = append(scumFileArr, scumF)
		}
	}

	//fmt.Println("远程文件为:", scumFileArr)

	//本地文件提取
	var localFileArr []scumFile
	// 使用 Walk 函数遍历目录下的所有文件和子目录
	err = filepath.Walk(f.config.localDir, func(path string, info os.FileInfo, err error) error {
		if err != nil {
			fmt.Printf("Error accessing path %s: %v\n", path, err)
			panic(err.Error())
			return nil
		}

		// 如果是文件，打印文件名和文件大小
		if !info.IsDir() {
			localFile := scumFile{name: info.Name(), size: info.Size()}
			localFileArr = append(localFileArr, localFile)
			//fmt.Printf("本地文件: %s, Size: %d bytes\n", path, info.Size())
		}

		return nil
	})

	//fmt.Println("本地文件为:", localFileArr)

	//结合本地和远程文件 分析需要下载的文件
	var fileDownloadStatus bool //文件下载状态
	var downloadFileArr []scumFile
	var deleteFile bool //删除文件状态
	for _, ftpFile := range scumFileArr {
		//fmt.Println("处理文件:", ftpFile)
		fileDownloadStatus = true
		deleteFile = false
		for _, localFile := range localFileArr {
			if ftpFile.name == localFile.name {
				//fmt.Println("文件相同:", ftpFile.name, localFile.name)
				deleteFile = true
				if ftpFile.size == localFile.size {
					//大小相同  不下载
					fileDownloadStatus = false
					break
				} else {
					//大小不同 需要下载
					break
				}
			}
		}
		//fmt.Println("处理文件:", ftpFile, "状态:", fileDownloadStatus)
		if fileDownloadStatus {
			downloadFile := scumFile{name: ftpFile.name, size: ftpFile.size, status: deleteFile}
			downloadFileArr = append(downloadFileArr, downloadFile)
		}
	}

	return downloadFileArr, true
}

// 反射拿到对象 强行关闭
func forceCloseFTPConnection(client *FtpClient.ServerConn) error {
	// 通过反射获取 ServerConn 结构体的 netConn 字段
	v := reflect.ValueOf(client).Elem()
	netConnField := v.FieldByName("netConn")

	// 检查字段是否存在且类型正确
	if !netConnField.IsValid() || netConnField.IsNil() {
		return fmt.Errorf("netConn field not found or is nil")
	}

	// 获取 net.Conn 接口实例
	conn := netConnField.Interface().(net.Conn)

	// 强制关闭连接
	return conn.Close()
}

// 打开ssh连接
func (f *gpFtp) ConnectFtp() (*FtpClient.ServerConn, bool, error) {
	fmt.Println("打印配置信息", f.sshClient)
	fmt.Println("打印配置信息", f.config)

	ConnFtp, errftp := net.DialTimeout("tcp", f.config.Address+":"+f.config.port, 20*time.Second)

	println("连接数据", ConnFtp, errftp)
	// 2. 设置读写超时
	deadline := time.Now().Add(5 * time.Second)
	_ = ConnFtp.SetDeadline(deadline)

	// 3. 读取初始响应（FTP 服务器通常会发送 "220" 欢迎消息）
	reader := bufio.NewReader(ConnFtp)
	initialResponse, err := reader.ReadString('\n')
	if err != nil {
		ConnFtp.Close()
		panic("ip或端口错误")
		return nil, false, err
	}
	// 4. 检查初始响应是否是 FTP 格式（例如 "220 ..."）
	if !isFTPResponse(initialResponse) {
		ConnFtp.Close()
		panic("ip或端口错误")
		return nil, false, err
	}
	ConnFtp.Close()

	/*ConnFtp, errftp = net.DialTimeout("tcp", f.config.Address+":"+f.config.port, 20*time.Second)

	println("连接数据", ConnFtp, errftp)
	// 2. 设置读写超时
	deadline = time.Now().Add(20 * time.Second)
	_ = ConnFtp.SetDeadline(deadline)
	*/
	// 建立 SSH 连接
	/*client, err := FtpClient.Dial(f.config.Address+":"+f.config.port,
	FtpClient.DialWithDialFunc(
		func(network, address string) (net.Conn, error) {
			return ConnFtp, errftp
		}))
	*/

	client, err := FtpClient.Dial(f.config.Address+":"+f.config.port, FtpClient.DialWithTimeout(20*time.Second))
	if err != nil {
		f.Log.FtpLogGer2("FTP 连接错误:", err)
		fmt.Println("FTP 连接错误:", err)
		return client, false, err
	}
	err = client.Login(f.config.userName, f.config.password)
	if err != nil {
		f.Log.FtpLogGer2("FTP 登录错误:", err)
		fmt.Println("FTP 登录错误:", err)
		return client, false, err
	}
	fmt.Println("FTP 连接成功")
	return client, true, err
}

// 检查响应是否符合 FTP 协议（状态码为三位数字开头）
func isFTPResponse(response string) bool {
	response = strings.TrimSpace(response)
	println("response 数据", response)
	if len(response) < 3 {
		return false
	}
	// 检查是否是三位数字开头（例如 "211-Features:" 或 "220 Welcome"）
	for i := 0; i < 3; i++ {
		if response[i] < '0' || response[i] > '9' {
			return false
		}
	}
	return true
}

type timeoutConn struct {
	net.Conn
	ReadTimeout  time.Duration
	WriteTimeout time.Duration
}

func (c *timeoutConn) Read(b []byte) (n int, err error) {
	if c.ReadTimeout > 0 {
		_ = c.Conn.SetReadDeadline(time.Now().Add(c.ReadTimeout))
	}
	return c.Conn.Read(b)
}

func (c *timeoutConn) Write(b []byte) (n int, err error) {
	if c.WriteTimeout > 0 {
		_ = c.Conn.SetWriteDeadline(time.Now().Add(c.WriteTimeout))
	}
	return c.Conn.Write(b)
}

// 协程中下载文件 防卡死
func FtpRetr(FtpConn **FtpClient.ServerConn, file string, remoteFile **FtpClient.Response, errR *error, status *bool) {
	//FtpClient.Respons  是一个指针类型的变量  这里要传递一个指向指针的 指针变量 所以要用  **
	*status = false
	remoteFileR, err := (*FtpConn).Retr(file)
	if err != nil {
		*status = false
	} else {
		*status = true
	}
	*remoteFile = remoteFileR
	*errR = err
}

// 下载文件
func (f *gpFtp) DownloadFile(downloadFileArr []scumFile) {

	var remoteFile *FtpClient.Response
	var err error
	var fileStatus bool
	for key, file := range downloadFileArr {

		//重复三次打开文件  防错
		for i := 0; i < 4; i++ {
			fileStatus = false
			//go 协程下载防止  网络卡死 挂起 导致协程卡死
			go FtpRetr(&f.sshClient, file.name, &remoteFile, &err, &fileStatus)
			for j := 0; j < 120; j++ {
				// 休眠一段时间
				time.Sleep(1 * time.Second)
				//设定2分钟超时
				if fileStatus {
					break
				}
			}

			if fileStatus {
				fmt.Println("FTP下载文件成功")
				break
			}

			if err != nil {
				fmt.Println("获取文件错误:", "第", i+1, "次", err)
				f.Log.FtpLogGer2("获取文件列表错误", err)
			}

		}

		if !fileStatus {
			f.Log.FtpLogGer2("下载文件失败", fmt.Sprintf("开始返回", "第", 1, "次", err))
			f.sshStatus = false
			panic(err)
		}

		//f.sshClient.re
		//打开三次失败列入下载失败列表
		if fileStatus == false {
			downloadFileArr[key].dwStatus = false
			continue
		}

		//删除本地文件
		if file.status {
			// 删除文件  liunx 路径要更换

			err := os.Remove(filepath.Join(f.config.localDir + "/" + file.name))
			if err != nil {
				panic(err)
				fmt.Println("Error deleting file:", err)
				return
			}
		}

		//创建本地文件

		dstFile, err := os.Create(filepath.Join(f.config.localDir + "/" + file.name))
		if err != nil {
			fmt.Println("打开本地文件错误:", err)
			panic(err)
			return
		}
		buf, err := io.ReadAll(remoteFile)
		//读完后关闭文件下载
		remoteFile.Close()
		_, err = dstFile.Write(buf)
		if err != nil {
			if err.Error() == "connection lost" {
				f.sftpStatus = false
			}
			fmt.Println("错误:", err)
			return
		}
		fmt.Println("下载大小:", len(buf))
		if fileStatus == false {
			downloadFileArr[key].dwStatus = true
			continue
		}
	}
}

// 关闭连接
func (f *gpFtp) CloseConnect() {
	//f.sftpClient.Close()
	f.sshClient.Quit()
}

// 获取下载的文件
func (d *GpFtpS) GetDownloadFile(id int64, scumFtpDir string) []scumFile {
	var downloadFile []scumFile
	SmFtpConnectInfo := d.ftpConnectInfo.GetConnectInfo(id)
	filepath.Walk(scumFtpDir, func(path string, info os.FileInfo, err error) error {
		//fmt.Println("获取文件时间")
		if err != nil {
			//fmt.Println("错误")
			return err // 返回遍历过程中遇到的任何错误
		}

		// 判断当前遍历到的是否是文件（非目录）
		if info.IsDir() {
			return nil
		}
		modTime := info.ModTime().Unix()
		//fmt.Println("获取文件时间", modTime, SmFtpConnectInfo.ParsingAt)
		if modTime > SmFtpConnectInfo.ParsingAt {
			//fmt.Println("获取文件时间1", modTime, SmFtpConnectInfo.ParsingAt)
			downloadFilex := scumFile{name: info.Name(), size: info.Size(), status: true, dwStatus: false}
			downloadFile = append(downloadFile, downloadFilex)
		}

		// 如果不需要遍历子目录中的文件，可以在这里是返回nil以结束遍历
		// return nil

		// 否则，继续遍历
		return nil
	})
	//fmt.Println("所有文件", downloadFile)
	return downloadFile
}

//获取信息

//获取判断目录

//获取连接ftp
